package org

import (
	"d-serv-go/server/core/base"
	"d-serv-go/server/core/bean"
	"d-serv-go/server/core/cache"
	"d-serv-go/server/core/consts"
	"d-serv-go/server/core/db"
	"d-serv-go/server/core/util"
	"errors"
)

type userMgr struct {
}

func (m userMgr) GetUserStateByToken(token string) *bean.UserStateBean {
	if userState, ok := cache.CacheMgr.Get(token, consts.CACHE_TOKEN_USERSTATE).(*bean.UserStateBean); ok {
		return userState.Copy()
	}
	return nil
}

func (m userMgr) GetUser(userCode string) (*db.UserBean, error) {
	if userBean, ok := cache.CacheMgr.Get(userCode, consts.CACHE_TYPE_USER).(*db.UserBean); ok {
		return userBean, nil
	}
	user, err := db.ServDao.FindById(consts.SY_ORG_USER, userCode, false)
	if user == nil || err != nil {
		return nil, base.NewTipErr(db.Ctx().GetSyMsg("SY_USER_NOT_FOUND", userCode))
	} else {
		// TODO 查询构建好ROLE_CODES、DEPT_CODES 等

		userBean := db.NewUserBean2(user)
		cache.CacheMgr.Set(userCode, userBean, consts.CACHE_TYPE_USER)
		return userBean, nil
	}
}

func (m userMgr) SaveUserState(state *bean.UserStateBean, checkExists bool) bool {
	isNew := true
	if checkExists { // 检查用户状态信息
		userCode := state.GetStr("USER_CODE")
		param := db.NewSqlBean()
		param.And("USER_CODE", userCode)
		if i, err := db.ServDao.Count(consts.SY_ORG_USER_STATE, param); err == nil && i > 0 { // 如果数据已存在调整为更新模式
			isNew = false
			state.SetId(userCode)
		}
	}
	// 加入队列，单线程维护更新state
	//if(state.Contains("USER_LAST_LOGIN") && VertxMgr.vertx != null) {
	//	VertxMgr.vertx.eventBus().send(VertxEvent.CACHE_USER_USERSTATE, new JsonObject().mapFrom(state));
	//}

	// log.Info("usermgr.SaveUserState")
	return isNew
}

func (m userMgr) GetUserState(userCode string) *bean.UserStateBean {
	if userState, ok := cache.CacheMgr.Get(userCode, consts.CACHE_USER_USERSTATE).(*bean.UserStateBean); ok {
		return userState.Copy()
	} else {
		userState, _ := db.ServDao.FindById(consts.SY_ORG_USER_STATE, userCode, false)
		if userState != nil {
			us := &bean.UserStateBean{
				Bean: *userState,
			}
			return us
		}
	}
	return nil
}

func (m userMgr) SetTokenUserStateCache(token string, state *bean.UserStateBean) {
	cache.CacheMgr.Set(token, state, consts.CACHE_TOKEN_USERSTATE)
}

func (m userMgr) SetUserTokenCache(userCode string, state *bean.UserStateBean) {
	cache.CacheMgr.Set(userCode, state, consts.CACHE_USER_USERSTATE)
}

func (m userMgr) GetUserByLoginName(loginName string, cmpyCode string) (*db.UserBean, error) {
	match := bean.NewBean("")
	match.Set("USER_LOGIN_NAME", loginName)
	dict := db.DictMgr.GetDict("SY_ORG_USER")
	users := db.DictMgr.GetItemList(dict, cmpyCode)
	beans := util.BeanUtil.GetListByMatch(match, users, 1)
	if len(beans) > 0 {
		return db.UserMgr.GetUser(beans[0].GetStr("ID"))
	} else {
		return nil, errors.New(db.Ctx().GetSyMsg("SY_USER_NOT_FOUND", loginName+":"+cmpyCode))
	}
}

func (m userMgr) GetCacheVarMap(userCode string) map[string]interface{} {
	value := cache.CacheMgr.Get(userCode, consts.CACHE_TYPE_USER_VAR)
	if value != nil {
		return value.(map[string]interface{})
	}
	return nil
}

func (m userMgr) SetCacheVarMap(userCode string, varMap map[string]interface{}) {
	cache.CacheMgr.Set(userCode, varMap, consts.CACHE_TYPE_USER_VAR)
}

func (m userMgr) GetCacheUser(userCode string) *db.UserBean {
	if userBean, ok := cache.CacheMgr.Get(userCode, consts.CACHE_TYPE_USER).(*db.UserBean); ok {
		return userBean
	}
	return nil
}

func (m *userMgr) SetCacheMenuList(userCode string, menuList []*bean.Bean) {
	cache.CacheMgr.Set(userCode, menuList, consts.CACHE_TYPE_USER_MENU) // 设置缓存
}

func (m *userMgr) GetCacheMenuList(userCode string) []*bean.Bean {
	if menuTree, ok := cache.CacheMgr.Get(userCode, consts.CACHE_TYPE_USER_MENU).([]*bean.Bean); ok {
		return menuTree
	} else {
		return db.MenuMgr.MenuToCache(userCode)
	}
}

func (m *userMgr) RemoveTokenUserStateCache(token string) {
	cache.CacheMgr.Remove(token, consts.CACHE_TOKEN_USERSTATE)
}

func NewUserMgr() *userMgr {
	return &userMgr{}
}
